/*
 * @Author: 0x9DEFA478
 * @Date: 2021-03-11 17:53:34
 * @LastEditTime: 2025-08-22 21:21:03
 * @LastEditors: 0x9DEFA478
 * @Description: 自定义字符串操作
 * 
 */
#include "./H_String.h"
#include "./H_StringFormat.h"




Hsize H_StringLength(const char* String){
  Hsize r=0;
  while(String[r]!='\0'){
    r++;
  }
  return r;
}

Hsize H_StringCopy(Hbyte* Buffer,Hsize BufferSize,const char* String){
  Hsize r=0;
  char c;
  while((r<BufferSize)&&((c=String[r])!='\0')){
    Buffer[r]=(Hbyte)c;
    r++;
  }
  while(String[r]!='\0'){
    r++;
  }
  return r;
}

Hsize H_StringFindFirstChar(const char* String,char Ch){
  Hsize r;
  char c;

  r=0;
  while((c=String[r])!='\0'){
    if(c==Ch){
      return r;
    }
    r++;
  }
  return -1;
}

int H_StringIsSuffix(const char* String,const char* Suffix){
  Hsize stringLen;
  Hsize suffixLen;

  stringLen=H_StringLength(String);
  suffixLen=H_StringLength(Suffix);

  if(suffixLen<stringLen){
    return 0;
  }

  while((stringLen>0)&&(suffixLen>0)){
    stringLen--;
    suffixLen--;
    if(String[stringLen]!=Suffix[suffixLen]){
      return 0;
    }
  }

  return 1;
}

Hsize H_UTF8_ConvertTo_Unicode(const char* UTF_String,Char32* Unicode){
  unsigned char c;
  Hsize index;
  Huint32 unicode;
  int cnt;

  index=0;

  c=(unsigned char)UTF_String[index];
  if(c=='\0'){
    return 0;
  }

  index++;

  if((c&0x80U)==0x00U){
    *Unicode=c;
    return index;
  }
  
  cnt=0;
  do{
    cnt++;
    c<<=1;
  }while((c&0x80U)!=0x00U);//计算多少字节的UTF8
  
  if((cnt<2)||(cnt>6)){//至少2字节 且 32bit最多6字节
    return -index;
  }
  unicode=c>>cnt;

  cnt--;
  while((cnt>0)&&((c=UTF_String[index])!='\0')){
    if((c&0xC0U)!=0x80U){
      break;//错误的UTF8序列, 可能的错误的字符由下一次UTF8循环处理
    }
    unicode<<=6;
    unicode|=(Huint16)(c&0x3FU);
    index++;
    cnt--;
  }
  if(cnt>0){
    return -index;//不完整的unicode
  }

  *Unicode=(Char32)unicode;

  return index;
}


typedef struct{
  H_StringFormat_CharOutput CharOutput;
  Hbyte* Pointer;
  Hsize LastSize;
}H_StringPrintf_CharOutput;

static int Output(H_StringFormat_CharOutput* CharOutput,char c){
  H_StringPrintf_CharOutput* StringPrintf_CharOutput;
  Hsize LastSize;
  Hbyte* Pointer;

  StringPrintf_CharOutput=cH_GetParentPointer(CharOutput,H_StringPrintf_CharOutput,CharOutput);

  LastSize=StringPrintf_CharOutput->LastSize;
  if(LastSize<1){
    return -1;
  }

  Pointer=StringPrintf_CharOutput->Pointer;
  *Pointer=c;
  Pointer++;
  LastSize--;
  StringPrintf_CharOutput->Pointer=Pointer;
  StringPrintf_CharOutput->LastSize=LastSize;

  return 0;
}

Hsize H_StringPrintf(Hbyte* Buffer,Hsize BufferSize,const char* Format,...){
  va_list Params;
  H_StringPrintf_CharOutput CharOutput;
  int r;

  CharOutput.CharOutput.Output=Output;
  CharOutput.Pointer=Buffer;
  CharOutput.LastSize=BufferSize;
  
  va_start(Params,Format);

  r=H_StringFormat(&CharOutput.CharOutput,Format,&Params);

  va_end(Params);

  if(r<BufferSize){
    Buffer[r]='\0';
  }

  return r;
}



